﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace vueweb
{
	public class SessionEncodedKey
	{
		private string _keyString;
		private int? _hashCode;

		internal SessionEncodedKey(string key)
		{
			_keyString = key;
			KeyBytes = Encoding.UTF8.GetBytes(key);
		}

		public SessionEncodedKey(byte[] key)
		{
			KeyBytes = key;
		}

		internal string KeyString
		{
			get
			{
				if (_keyString == null)
				{
					_keyString = Encoding.UTF8.GetString(KeyBytes, 0, KeyBytes.Length);
				}
				return _keyString;
			}
		}

		internal byte[] KeyBytes { get; private set; }

		public override bool Equals(object obj)
		{
			var otherKey = obj as SessionEncodedKey;
			if (otherKey == null)
			{
				return false;
			}
			if (KeyBytes.Length != otherKey.KeyBytes.Length)
			{
				return false;
			}
			if (_hashCode.HasValue && otherKey._hashCode.HasValue
				&& _hashCode.Value != otherKey._hashCode.Value)
			{
				return false;
			}
			for (int i = 0; i < KeyBytes.Length; i++)
			{
				if (KeyBytes[i] != otherKey.KeyBytes[i])
				{
					return false;
				}
			}
			return true;
		}
		private byte[] key = {0x11, 0x22, 0x22, 0x33, 0x33, 0x44, 0x44, 0x55,
				0x55, 0x66, 0x66, 0x77, 0x77 ,0x88, 0x88, 0x00};
		public override int GetHashCode()
		{
			if (!_hashCode.HasValue)
			{
				var hash = new Org.BouncyCastle.Crypto.Macs.SipHash();
				hash.Init(new Org.BouncyCastle.Crypto.Parameters.KeyParameter(key));
				hash.BlockUpdate(KeyBytes, 0, KeyBytes.Length);
				_hashCode = hash.DoFinal(KeyBytes, 0);
			}
			return _hashCode.Value;
		}

		public override string ToString()
		{
			return KeyString;
		}
	}
}
